-- UIBottomMenu
-- Create by weism
-- 主界面的底部按钮

require "game/ui/form/talent/UITalentMain"
require "game/ui/base/TextStyleM"
require "game/ui/form/market/UIMarketMain"
require "game/ui/form/combat_stat/UICombatStat"
require "game/ui/form/workshop/UINewWorkshop"
require "game/ui/form/sky_city/UISkyCity"

UIBottomMenu = class("UIBottomMenu", function()
    return cc.Layer:create();
end);

function UIBottomMenu.create()
    return UIBottomMenu.new();
end

-- 底部菜单的个数
local BOTTOM_MENU_NUM = 5;

local nodeL;

-- 内部函数声明
local resize;
local updateState;
local onHero;
local onAlchemy;
local onTalent;
local onShop;
local onFriend;
local onEvent;
local onPvp;
local onAirShip;

local icons = { "alchemy", "slime", "friend" , "shop", "talent", };
local locIcons = { "alchemy", "slime", "pvp" , "shop", "event", };

-- 构造函数
function UIBottomMenu:ctor()
    self:setName("UIBottomMenu");

    local node = cc.CSLoader:createNode("layout/main/BottomMenu.csb");
    self.node = node;
    self:addChild(node);
    nodeL = node;

    --当前选中元素
    self.selectedIndex = -1;

    local funcs = { onAlchemy, onHero, onAirShip, onShop, onEvent, };

    for i = 1, BOTTOM_MENU_NUM do
        local bg = findChildByName(node, "panel/bg"..i);

        -- 设置按钮的标签名称
        local nameIcon = findChildByName(bg, "name_icon");
        local nameIconPath = getLocImg(locIcons[i]);
        nameIcon:loadTexture(nameIconPath);

        local iconImg = bg:getChildByName("icon");

        bg:setVisible(false);
        bg:setTag(i);
        bg.type = locIcons[i];

        bg:addTouchEventListener(function(sender, eventType)
            local function callback(forceGrade)
                self:onForcePress(sender, forceGrade);
            end

            local function cancelCallback()
                sender.forceGrade2Handled = false;
                sender.forceGrade4Handled = false;

                stopForcePressButtonEffect();
            end

            -- 处理3Dtouch
            if handleForcePress(sender, eventType, callback, cancelCallback) then
                return;
            end

            if eventType == ccui.TouchEventType.ended then
                -- 防止重复点击
                if self.isClicking then
                    print("无法点击")
                    return;
                end

                self.isClicking = true;

                local index = sender:getTag();
                self.selectedIndex = index;

                -- 图片缩放一下再进行点击的处理
                local iconImg = bg:getChildByName("icon");
                iconImg:setScale(1.0);
                iconImg:stopAllActions();
                local scaleUp = cc.ScaleTo:create(0.1, 1.2);
                local scaleDown = cc.ScaleTo:create(0.1, 1);

                local onClick = cc.CallFunc:create(function()
                    funcs[index](self);
                end);

                local delay = cc.DelayTime:create(0.2);
                local callFunc = cc.CallFunc:create(function()
                    self.isClicking = false;
                end);

                iconImg:runAction(cc.Sequence:create(scaleUp, scaleDown, onClick, delay, callFunc));

                self:updateState(true);
            end
        end);
    end

    -- 关注消息以重绘
    ME.user.dbase:registerCb("UIBottomMenu", { "dungeon_progress", }, function()
        self:updateState();
    end);

    -- 金币变动的回调处理
    ME.user.dbase:registerCb("UIBottomMenu", { "money", }, function()
        self:updateAlchemyBubble();
    end);

    -- 注册工坊信息更新回调
    EventMgr.register("UIBottomMenu", event.WORKSHOP_INFO_UPDATED, function()
        self:updateAlchemyBubble();
    end);

    -- 注册事件
    EventMgr.register("UIBottomMenu", event.TIME_OFFSET_ARRIVER, function()
        self:updateHeroBubble();
    end);

    -- 注册事件
    EventMgr.register("UIBottomMenu", event.TAKE_FRUIT_BONUS, function(classId)
        self:updateHeroBubble();
    end);

    -- 签到事件
    EventMgr.register("UIBottomMenu", event.SIGN_IN_BONUS, function(classId)
        self:updateHeroBubble();
    end);

    -- 注册英雄穿上装备的回调
    EventMgr.register("UIBottomMenu", event.EQUIP, function(args)
        self:updateHeroBubble();
    end);

    -- 炼金强化泡泡已提醒
    EventMgr.register("UIBottomMenu", event.WORKSHOP_ITEM_REMINDED, function()
        self:updateAlchemyBubble();
    end);

    -- 关注团购奖励领取事件
    EventMgr.register("UIBottomMenu", event.TAKE_GROUPPURCHASE_BONUS, function(args)
        self:updateShopBubble();
    end);

    -- 关注豪华礼包领取事件
    EventMgr.register("UIBottomMenu", event.TAKE_GIFTS_BONUS, function(args)
        self:updateShopBubble();
    end);

    -- 关注MSG_IN_DUNGEON消息回调
    MSG.registerMsgTrigger("UIBottomMenu", "MSG_IN_DUNGEON", function(para)
        self:checkInDungeonState();
    end);

    -- 关注玩家属性变化
    EventMgr.register("UIBottomMenu", event.USER_INFO_UPDATED, function(para)
        if not self:isVisible() then
            -- print("UIBottomMenu不可见，无需处理, desc:"..para)
            return;
        end

        if para == "ship_energy" then
            self:updateAirShipBubble();
        elseif para == "idle_worker_num" then
            self:updateAlchemyBubble();
        end
    end);

    -- 界面析构后，需要清理下
    self:registerScriptHandler(function(ev)
        if ev == "exit" then
            -- 移除所有事件回调
            ME.user.dbase:removeCb("UIBottomMenu", { "dungeon_progress", });
            ME.user.dbase:removeCb("UIBottomMenu", { "money", });
            EventMgr.removeAll("UIBottomMenu");
        end
    end);

    self:resize(node);

    self:updateState();

    self:updateAirShipBubble();

    -- 登录后检测是否在迷宫中
    if DungeonM.isInDungeon() then
        self:checkInDungeonState();
    end
end

-- 3Dtouch触发
function UIBottomMenu:onForcePress(sender, forceGrade)
    if forceGrade >= FORCE_GRADE_4 and not sender.forceGrade4Handled then
        Vibrator.vibrate(1);
        stopForcePressButtonEffect();
        if sender:getTag() == 1 then
            if ScoutM.isExploring() then
                -- 正在探索，直接打开界面
                local uiScout = UIScoutInfo.create(false, false);
                UIMgr.getCurrentScene():addForm(uiScout);
            end
        elseif sender:getTag() == 2 then
            if TrainingM.getLevel() > 0 then
                local uiForm = UITrainingMain.create();
                UIMgr.getCurrentScene():addForm(uiForm);
            end
        end

        sender.forceGrade4Handled = true;
    elseif forceGrade >= FORCE_GRADE_3 and not sender.forceGrade2Handled then
        local w = cc.Director:getInstance():getOpenGLView():getFrameSize().width;
        local h = cc.Director:getInstance():getOpenGLView():getFrameSize().height;
        startForcePressButtonEffect(sender, math.min(w / DESIGN_WIDTH, h / DESIGN_HEIGHT));

        sender.forceGrade2Handled = true;
    end
end

-- 更新语言
function UIBottomMenu:changeLanguage()
    local locNames = {"alchemy", "slime", "talent", "shop", "friend"};
    for i = 1, #locNames do
    local label = findChildByName(self.node, "bg".. i .. "/name");
        if label then
            TextStyleM.setTextStyle(label, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
            label:setString(getLocStr(locNames[i]));
        end
    end
end

-- 更新状态
function UIBottomMenu:updateState(skipBubble)
    local offset = 0;
    local openList = self:getOpenList();

    for i = 1, BOTTOM_MENU_NUM do
        local bg = findChildByName(self.node, "panel/bg"..i);
        local index = table.indexOf(openList, bg.type);
        if bg.type and index > 0 then
            bg:setVisible(true);

            bg.oldPos = cc.p(72 + 124 * (index - 1), bg.oldPos.y or bg:getPositionY());
        else
            bg:setVisible(false);
        end
    end

    local panel = findChildByName(self.node, "panel");
    local oldScale = panel:getScale();
    offset = 131 * (BOTTOM_MENU_NUM - #openList) / 2 * oldScale;

    panel:setPositionX(self.panelPosX + offset);

    if not skipBubble then
        self:updateAlchemyBubble();
        self:updateHeroBubble();
        self:updateShopBubble();
    end
end

-- 计算需要显示的按钮列表
function UIBottomMenu:getOpenList()
    -- 炼金坊和冈布奥按钮默认开启
    local openList = { "alchemy", "slime", };

    -- 天空之城已开启
    if NewAirShipM.isFinishGuide() then
        table.insert(openList, "pvp");
    end

    -- 商城已开启
    if MarketM.isMarketFuncOpen() then
        table.insert(openList, "shop");
    end

    return openList;
end

-- 更新炼金炉泡泡
function UIBottomMenu:updateAlchemyBubble()
    -- 如果工坊有空闲工人，出现泡泡，泡泡中显示空闲工人数
    local hintNode = findChildByName(self.node, "panel/bg1/hint");

    local idleNum = AlchemyWorkshopM.getIdleWorkerNum();
    checkBlueBubbleStatus(hintNode, idleNum);

    -- 如果没有空闲工人，但是工坊可强化或者探索完成，或者月卡奖励领取或者可升级，显示叹号泡泡
    if idleNum == 0 then
        local ready = AlchemyWorkshopM.readyForStrengthen();

        if ScoutM.getScoutCount() > 0 and ScoutM.getLeftTime() <= 10 then
            -- 客户端比服务端冗余10s时间，最后一次奖励
            ready = true;
            self.ScoutTip = true;
        end
        checkBlueBubbleStatus(hintNode, ready);

        -- 检查是否有月卡奖励可领取或者可升级
        if not ready then
            local isCanTake = SuperiorM.cantakeBonus();
            local isCanLevelUp = SuperiorM.canUpgrade();
            checkBlueBubbleStatus(hintNode, isCanTake or isCanLevelUp);
        end
    end
end

-- 更新冈布奥泡泡
function UIBottomMenu:updateHeroBubble()
    -- 如果有世界树奖励可领取，出现泡泡
    local hintNode = findChildByName(self.node, "panel/bg2/hint");
    local num = TalentFruitBonusM.getAvailableBonuNum();

    -- 可喂食英雄数量
    local heroList = PetM.getHeroListCanFeedOrEquip();
    num = num + #heroList;

    -- 可进阶
    if (TrainingM.getState() == TrainingM.TRAINING_STATE_FINISH)
        or (TrainingM.getState() == TrainingM.TRAINING_STATE_PREPARE and TrainingM.canHeroUpgrade())
        or (FeatureItemM.isFeatureOpen("heart") and FeatureItemM.isFeatureNeedReminder("heart")) then
        num = num + 1;
    end

    -- 可签到
    if NewSignInM.canSignIn() then
        num = num + 1;
    end

    checkBlueBubbleStatus(hintNode, num);
end

-- 更新商城泡泡
function UIBottomMenu:updateShopBubble()
    -- 如果豪华礼包有可领取的奖励
    local hintNode = findChildByName(self.node, "panel/bg4/hint");
    local totalNum = GiftM.calcAllCanTakeBonus() + GroupPurchaseM.getALlCanTakeBonusNum();

    if MarketM.canTakeFirstChargeBonus() then
        totalNum = totalNum + 1;
    end
    checkBlueBubbleStatus(hintNode, totalNum);
end

-- 更新天空之城泡泡
function UIBottomMenu:updateAirShipBubble()
    local hintNode = findChildByName(self.node, "panel/bg3/hint");
    local activedShip = NewAirShipM.getActiveAirShip();

    -- 1.雷达能量满，显示提示
    local maxEnergy = NewAirShipM.query(activedShip, "max_energy") or 0;
    local curEnergy = ME.user.dbase:query("ship_energy", 0);
    local isEnergyFull = curEnergy >= maxEnergy;

    -- 2.出战阵容有空位且有可以出战的宠物或者机器人，显示提示
    local maxNum = SkyCombatM.getMaxPetNum();
    local armyNum = #SkyCombatM.getSkyArmy();
    local robatList = SkyRobotM.getRobotsByCamp(ME.user.dbase:query("activedSkyGroup"));
    -- 计算下出战了多少机器人
    local robatNum = 0;
    for _, num in pairs(robatList) do
        robatNum = robatNum + num;
    end

    local freeRobot = SkyRobotM.fetchRobotList();
    local campId = ME.user.dbase:query("activedSkyGroup") or 2; -- 默认奥鲁维
    local freePetNum = #CampM.getCampMyPet(campId) - armyNum;
    local isCampSatisfy = armyNum + robatNum < maxNum and (#freeRobot > 0 or freePetNum > 0);

    -- 是否显示提示标签
    checkBlueBubbleStatus(hintNode, isEnergyFull or isCampSatisfy);
end

-- 检查暂离状态
function UIBottomMenu:checkPauseState()
    local blendColor = TextStyleM.TEXT_COLOR_BLEND;
    local normalColor = TextStyleM.TEXT_COLOR_NORMAL;

    local function isOpenFunc(index)
        -- if index == 2 then
        --     -- 目前暂离状态下仅slime操作是受限制的
        --     return false;
        -- else
        --     return true;
        -- end

        return true;
    end

    for i = 1, BOTTOM_MENU_NUM do
        local bg = findChildByName(self.node, "panel/bg"..i);
        if DungeonM.isInDungeon() and not isOpenFunc(i) then
            bg:setColor(blendColor);
        else
            bg:setColor(normalColor);
        end
    end
end

-- 检查在迷宫的状态
function UIBottomMenu:checkInDungeonState()
    local blendColor = TextStyleM.TEXT_COLOR_BLEND;
    local normalColor = TextStyleM.TEXT_COLOR_NORMAL;

    local function isOpenFunc(index)
        -- if index == 1 or index == 5 then
        --     return true;
        -- else
        --     return false;
        -- end

        return true;
    end

    for i = 1, BOTTOM_MENU_NUM do
        local bg = findChildByName(self.node, "panel/bg"..i);
        if DungeonM.isInDungeon() and not isOpenFunc(i) then
            bg:setColor(blendColor);
        else
            bg:setColor(normalColor);
        end
    end
end

-- 飞入效果
function UIBottomMenu:flyIn()
    local duration = 0.1;
    local offsetY = 300;

    local openList = self:getOpenList();

    local function play(node)
        node:stopAllActions();

        local pos = node.oldPos;
        local moveUp = cc.EaseIn:create(cc.MoveTo:create(duration, cc.p(pos.x, pos.y + 5)), 0.3);
        local moveDown = cc.EaseIn:create(cc.MoveTo:create(0.1, cc.p(pos.x, pos.y - 3)), 0.3);
        local moveUp2 = cc.EaseIn:create(cc.MoveTo:create(0.1, cc.p(pos.x, pos.y)), 0.3);
        local action = cc.Sequence:create(moveUp ,moveDown, moveUp2);

        node:setVisible(true);
        node:runAction(action);
    end

    -- 按钮逐一飞入
    local i = 1;
    for i = 1, BOTTOM_MENU_NUM do
        local bg = findChildByName(self.node, "panel/bg"..i);
        local pos = bg.oldPos;

        if bg.type and table.indexOf(openList, bg.type) > 0 then
            bg:setPosition(cc.p(pos.x, pos.y - offsetY));

            performWithDelay(bg, play, 0.1 + 0.03 * i);
        end
    end
end

-- 飞出效果
function UIBottomMenu:flyOut()
    local duration = 0.2;
    self:stopAllActions();
    local delay = cc.DelayTime:create(0.1);
    local move = cc.MoveBy:create(duration, cc.p(0, -300));
    self:runAction(cc.Sequence:create(delay, move));
end

-- 重新调整大小
function UIBottomMenu:resize()
    local node = self.node;
    local w = AlignM.frameSize.width;
    local h = AlignM.frameSize.height;
    node:setContentSize(w, h);

    local panel = findChildByName(node, "panel");
    panel:setPositionX(w / 2);
    self.panelPosX = w / 2;
    self.oldPos = cc.p(self:getPosition());

    panel:setScale(math.min(w / DESIGN_WIDTH, h / DESIGN_HEIGHT));

    for i = 1, BOTTOM_MENU_NUM do
        local bg = findChildByName(node, "panel/bg"..i);
        bg.oldPos = cc.p(bg:getPosition());
    end
end

-- 还原Bottom
function UIBottomMenu:setNormalColor()
    local normalColor = TextStyleM.TEXT_COLOR_NORMAL;

    for i = 1, BOTTOM_MENU_NUM do
        local bg = findChildByName(self.node, "panel/bg"..i);
        bg:setColor(normalColor);
    end
end

-- "冈布奥"按钮点击处理
onHero = function(self)
    UIMgr.getCurrentScene():removeFormByName("UIHeroMain");

    -- -- 如果在迷宫中，不能打开冈布奥界面
    -- if DungeonM.isInDungeon() then
    --     alert(getLocStr("pausing_forbid"));
    --     return;
    -- end

    -- 赶紧加速同步一次
    catch(SyncResourceM.speed_up_sync);

    UIMgr.getCurrentScene():removeFormByName("UITalentMain");
    local uiTalent = UITalentMain:create();
    UIMgr.getCurrentScene():addForm(uiTalent);
end

-- "炼金"按钮点击处理
onAlchemy = function(self)
    UIMgr.getCurrentScene():removeFormByName("UINewWorkshop");

    local uiWorkshop = UINewWorkshop:create();
    UIMgr.getCurrentScene():addForm(uiWorkshop);
end

-- "商店"按钮点击处理
onShop = function(self)
    UIMgr.getCurrentScene():removeFormByName("UIMarketMain");
    local uiMarketMain = UIMarketMain.create();
    UIMgr.getCurrentScene():addForm(uiMarketMain);
end

-- "PvP"点击处理
local count = 1;
onPvp = function(self)
    --local uiCombatStat = UICombatStat.create(CombatStatM.getCombatStat());
    --UIMgr.getCurrentScene():addForm(uiCombatStat);

    alert(getLocStr("function_is_not_open"));

--    local scene = UIMgr.getCurrentScene();
--    local snapshot = require "snapshot";
--
--    if not scene.snapshot1 then
--        scene.snapshot1 = snapshot();
--        print("生成快照1");
--    else
--        print("内存泄露报告：");
--        print("++++++++++++++++++++++++++++++++++++++++++++++++");
--        local snapshot2 = snapshot();
--        for k,v in pairs(snapshot2) do
--            if scene.snapshot1[k] == nil then
--                print(v);
--            end
--        end
--        print("++++++++++++++++++++++++++++++++++++++++++++++++");
--
--        scene.snapshot1 = nil;
--    end

--    if (count % 2) == 1 then
--        print(cc.Director:getInstance():getTextureCache():getCachedTextureInfo());
--    else
--        -- 清除无用纹理
--        UIMgr.clearUnusedTextures();
--    end
--
--    count = count + 1;
end

-- "飞船" 点击处理
onAirShip = function (self)
    if ServerStatusM.query(MODULE_SWITCH_AIRSHIP_CLOSE) == 1 then
        -- 弹出天空之城关闭提示框
        confirm2(CONFIRM_TYPE_OK, getLocStr("slime_note"), getLocStr("sky_city_is_close"));
        return;
    end

    local function onAirSip()
        local uiForm = UISkyCity.create();
        UIMgr.getCurrentScene():addForm(uiForm);
        AudioM.playFx("ui_open1");
    end

    -- 检查是否下载独立资源包
    checkExtraPackDownload(onAirSip);
end

-- "活动"点击处理
onEvent = function(self)

end

return UIBottomMenu;
